﻿using DomainModel;
using Repository.Interfaces;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Repository
{
    public class PatientRepository: IPatientRepository
    {
        private string _connectionString;

        public PatientRepository(string connectionString)
        {
            _connectionString = connectionString;
        }

        public int AddPatient(Patient patient)
        {
            using (var connection = new SqlConnection(_connectionString))
            {
                using (var command = new SqlCommand("InsertPatient", connection))
                {
                    command.CommandType = System.Data.CommandType.StoredProcedure;

                    command.Parameters.Add(new SqlParameter("@name", patient.Name));
                    command.Parameters.Add(new SqlParameter("@gender", patient.Gender.ToString()));
                    command.Parameters.Add(new SqlParameter("@dateOfBirth", patient.DateOfBirth));
                    command.Parameters.Add(new SqlParameter("@phoneNumber", patient.PhoneNumber));
                    command.Parameters.Add(new SqlParameter("@emailAddress", patient.EmailAddress));
                    command.Parameters.Add(new SqlParameter("@homeAddressLine1", patient.HomeAddress.Line1));
                    command.Parameters.Add(new SqlParameter("@homeAddressLine2", patient.HomeAddress.Line2));
                    command.Parameters.Add(new SqlParameter("@homeAddressCity", patient.HomeAddress.City));
                    command.Parameters.Add(new SqlParameter("@homeAddressState", patient.HomeAddress.State));
                    command.Parameters.Add(new SqlParameter("@homeAddressPostalCode", patient.HomeAddress.PostalCode));

                    var outParam = new SqlParameter("@medicalRecordNumber", SqlDbType.Int);
                    outParam.Direction = ParameterDirection.Output;
                    command.Parameters.Add(outParam);

                    connection.Open();
                    command.ExecuteNonQuery();

                    var mrn = (int)command.Parameters["@medicalRecordNumber"].Value;
                    return mrn;
                }
            }
        }

        public void UpdatePatient(Patient patient)
        {
            using (var connection = new SqlConnection(_connectionString))
            {
                using (var command = new SqlCommand("UpdatePatient", connection))
                {
                    command.CommandType = System.Data.CommandType.StoredProcedure;

                    command.Parameters.Add(new SqlParameter("@medicalRecordNumber", patient.MedicalRecordNumber));
                    command.Parameters.Add(new SqlParameter("@name", patient.Name));
                    command.Parameters.Add(new SqlParameter("@gender", patient.Gender.ToString()));
                    command.Parameters.Add(new SqlParameter("@dateOfBirth", patient.DateOfBirth));
                    command.Parameters.Add(new SqlParameter("@phoneNumber", patient.PhoneNumber));
                    command.Parameters.Add(new SqlParameter("@emailAddress", patient.EmailAddress));
                    command.Parameters.Add(new SqlParameter("@homeAddressLine1", patient.HomeAddress.Line1));
                    command.Parameters.Add(new SqlParameter("@homeAddressLine2", patient.HomeAddress.Line2));
                    command.Parameters.Add(new SqlParameter("@homeAddressCity", patient.HomeAddress.City));
                    command.Parameters.Add(new SqlParameter("@homeAddressState", patient.HomeAddress.State));
                    command.Parameters.Add(new SqlParameter("@homeAddressPostalCode", patient.HomeAddress.PostalCode));

                    connection.Open();
                    if (command.ExecuteNonQuery() == 0)
                    {
                        throw new Exception(string.Format("Patient with medical record number: {0} cannot be found.", patient.MedicalRecordNumber));
                    }
                }
            }
        }

        public Patient GetPatient(int mrn)
        {
            using (var connection = new SqlConnection(_connectionString))
            {
                using (var command = new SqlCommand("GetPatientByMedicalRecordNumber", connection))
                {
                    command.CommandType = System.Data.CommandType.StoredProcedure;
                    command.Parameters.Add(new SqlParameter("@medicalRecordNumber", mrn));
                    connection.Open();

                    var reader = command.ExecuteReader();
                    if (reader.Read())
                    {
                        return new Patient(reader);
                    }
                }
            }
            throw new Exception(string.Format("Patient with medical record number: {0} cannot be found.", mrn));
        }
    }
}
